#!/usr/bin/python
# -*- coding:utf-8 -*-
import uuid
import time
import pickle
import arrow

from bson import DBRef
from django.conf import settings
from django.utils import timezone
from django.contrib.auth.models import AnonymousUser
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import AuthenticationFailed
from mongoengine.errors import DoesNotExist, ValidationError
from utilities.captcha import Code
from utilities.redis import captcha_redis as redis_db
from utilities.djconsole import djconsole
from utilities.custom_exception import MaxMultipleDevicesError
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
from rest_framework_simplejwt.exceptions import InvalidToken, TokenError
from rest_framework.permissions import AllowAny
from utilities.viewsets import (
    CustomModelViewSet as ModelViewSet,
    CustomGenericViewSet
)
from utilities.meta_view import APIViewList
from utilities.log import log_login_success, log_login_fail, audit_log, log_logout
from utilities.api_send_message import send_message
from apps.account_manager.models import (
    User,
    UserGroups,
    Permissions,
    Tokens,
    OutUrls
)
from models.strategy import CustomProfileTemplate
from models.warn import WebReceivers
from models.vul import WhiteListKeywords, CustomKeywords
from apps.account_manager.serializers import (
    RegisterSerializer,
    PermissionSerializer,
    UserGroupSerializer,
    UserSerializer,
    CustomTokenObtainPairSerializer,
    CustomTokenRefreshSerializer,
    SerializerUserDetail,
    SerializerUserInfo,
    InPutApiTokenSerializer,
    OutputUrlSerializer
)
from apps.target.serializer import TargetGroups, destroy_target_groups
from apps.account_manager.account_utils import (
    is_login_limit,
    cut_login_counter,
    clear_login_counter,
    get_header_token,
    get_refresh_token_exp,
    delete_token,
    get_user_account_log
)
from apps.account_manager.error_message import PasswordError, NotActiveError
from apps.account_manager.mfa import (
    create_totp_qr_secret,
    create_qr_url,
    unhexlify_key,
    verify_token,
)
from apps.global_config.serializer import get_global_config
from utilities.enums import LogModuleName, LogTypeName, AuditLogAction
from utilities.errors import Error403
from utilities.utils import admin_permission_check


class MfaValidateMixin:
    def mfa_before(self, username, kind, data):
        now_time = int(time.time() * 1000)
        redis_db.set(f"{username}_{now_time}_{kind}", pickle.dumps(data), ex=300)
        return Response(
            data={
                "status": "success",
                "errcode": 0,
                "data": {
                    "is_mfa": True,
                    "link": f"api/v1/account/mfa_validate/",
                    "args": {"username": username, "time": now_time, "kind": kind},
                },
            }
        )

    def mode_change(self, redis_data):
        func = redis_data.get("func")
        data, log_data = func[0](*func[1])
        audit_log(request=self.request, **log_data)
        return Response(data=data, status=200)

    def shut_reboot(self, redis_data):
        func = redis_data.get("func")
        log_data = redis_data.get("log_data")
        audit_log(self.request, **log_data)
        if func == "reboot":
            data = djconsole.reboot(self.request)
        else:
            data = djconsole.shutdown(self.request)
        data = {"status": "success", "errcode": 0, "message": data}
        return Response(data=data, status=200)

    def login(self, redis_data):
        return Response(data=redis_data.get("res"), status=200)

    def mfa_after(self, kind, before_data):
        redis_data = pickle.loads(before_data)
        return getattr(self, kind)(redis_data)


class PermissionView(ModelViewSet):

    serializer_class = PermissionSerializer
    queryset = Permissions.objects.all()

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        collection = UserGroups._get_collection()
        if collection.find_one(
            {"permissions": {"$elemMatch": {"$eq": DBRef("permissions", instance.id)}}}
        ):
            return Response(
                data={"status": "fail", "message": f"权限 '{instance.name}' 使用中"},
                status=400,
            )
        instance.delete()
        log_data = {
            "module": "account_manager",
            "action": "del",
            "type": "permission",
            "desc": {"detail": f"删除权限{instance.name}"},
        }
        audit_log(request, **log_data)
        return Response(
            data={"status": "success", "message": f"删除权限{instance.name}成功"}, status=204
        )


class UserGroupView(ModelViewSet):

    serializer_class = UserGroupSerializer
    queryset = UserGroups.objects.all()

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        collection = User._get_collection()
        if collection.find_one(
            {"group": {"$elemMatch": {"$eq": DBRef("user_group", instance.id)}}}
        ):
            return Response(
                data={"status": "fail", "message": f"用户组 '{instance.name}' 使用中"},
                status=400,
            )
        instance.delete()
        log_data = {
            "module": "account_manager",
            "action": "del",
            "type": "user_group",
            "desc": {"detail": f"删除角色{instance.group}"},
        }
        audit_log(request, **log_data)
        return Response(
            data={"status": "success", "message": f"删除用户组 '{instance.name}' 成功"},
            status=204,
        )


class RegisterUserView(APIView):

    # permission_classes = [
    #     AllowAny,
    # ]

    def post(self, request, *args, **kwargs):
        data = request.data or {}
        data.pop("balance", 0)
        try:
            user = self.create_user(request.data)
            data = {
                "status": "success",
                "message": "注册成功",
                "data": {
                    "username": user.username,
                },
            }
            log_data = {
                "module": "account_manager",
                "action": "add",
                "type": "account",
                "operator": request.user.username,
                "desc": {
                    "detail": f"注册用户{user.username}|{[u.__str__() for u in user.group]}|{user.desc or ''}"
                },
            }
            audit_log(request, **log_data)
        except ValidationError as e:
            return Response(data={"status": "fail", "message": str(e)}, status=400)
        except Exception as e:
            raise e
        return Response(data)

    def create_user(self, data):
        self.validate_license_info()
        data.setdefault("group", getattr(settings, "DEFAULT_USER_GROUP", ""))

        if '管理员' in data['group']:
            data['is_superuser'] = True
            if self.request.user.username != 'admin':
                raise ValidationError()
        else:
            data['is_superuser'] = False

        data['parent_id'] = self.request.user.user_id
        serializer = RegisterSerializer(data=data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()
        return user

    def validate_license_info(self):
        license_info = djconsole.get_license_detail(self.request)
        max_user_count = int(license_info.get('max_user_number', -1))
        if User.objects.count() >= max_user_count:
            raise ValidationError(f"用户数量不能超过 {max_user_count} 个")


class ManagerRegisterUserView(RegisterUserView):
    def post(self, request, *args, **kwargs):
        data = request.data
        if not data.get("password"):
            data["password"] = uuid.uuid4().hex
        user = self.create_user(data)
        data = {
            "status": "success",
            "message": f"创建用户 {user.username} 成功",
            "data": {
                "username": user.username,
                "password": data["password"],
                "product": user.product,
                "group": [g.group for g in user.group],
            },
        }
        log_data = {
            "module": "account_manager",
            "action": "add",
            "type": "account",
            "desc": {
                "detail": f"管理员创建用户{user.username}|{[u.__str__() for u in user.group]}|{user.desc or ''}"
            },
        }
        audit_log(request, **log_data)
        return Response(data)


class LoginView(TokenObtainPairView, MfaValidateMixin):
    """
    post:
    登录, 参数， username， password， captcha
    """

    permission_classes = [
        AllowAny,
    ]
    serializer_class = CustomTokenObtainPairSerializer

    def post(self, request, *args, **kwargs):
        captcha = request.data.get("captcha")
        if not Code(request=request).check(captcha):
            log_login_fail(request, error="无效验证码")
            return Response(data={"status": "fail", "message": "验证码错误！"}, status=400)
        serializer = self.get_serializer(data=request.data)
        username = request.data.get("username").strip()
        obj_global_config = get_global_config()
        is_limit, count = is_login_limit(username, obj_global_config)
        if is_limit:
            log_login_fail(request, error=f"密码错误，超过登录限制")
            return Response(
                data={
                    "status": "fail",
                    "message": f"密码错误次数超过限制，请等待 {int(obj_global_config.locked_time)} "
                    f"分钟后再尝试或联系管理员解锁！",
                },
                status=400,
            )
        try:
            serializer.is_valid(raise_exception=True)
        except PasswordError:
            log_login_fail(request, error=f"密码错误，还可以尝试{count}次")
            if count == 0:
                return Response(
                    data={
                        "status": "fail",
                        "message": f"密码错误次数超过限制，请等待 {int(obj_global_config.locked_time)} "
                        f"分钟后再尝试或联系管理员解锁！",
                    },
                    status=400,
                )
            return Response(
                data={"status": "fail", "message": f"密码错误，还可以尝试{count}次"}, status=400
            )
        except NotActiveError as e:
            cut_login_counter(username)
            log_login_fail(request, error=str(e))
            return Response(data={"status": "fail", "message": str(e)}, status=400)
        except AuthenticationFailed:
            cut_login_counter(username)
            log_login_fail(request, error="用户不存在")
            return Response(data={"status": "fail", "message": "用户不存在"}, status=400)
        except MaxMultipleDevicesError:
            cut_login_counter(username)
            log_login_fail(request, error="超过登录终端数")
            return Response(data={
                "status": "fail",
                "message": f"管理员设置了同一账号同时只能在{obj_global_config.max_multiple_devices}个终端登录"},
                status=400)
        user = User.objects.get(username=username)
        clear_login_counter(username)
        self.update_login_info(serializer.user.username)
        log_login_success(request, group=User.objects.filter(username=username).first().group)
        if user.mfa:
            res = serializer.validated_data
            redis_data = {"func": [], "res": res}
            return self.mfa_before(username, "login", redis_data)
        return Response(serializer.validated_data, status=200)

    def update_login_info(self, username):
        user = User.objects.get(username=username)
        req_ip = self.request.META.get("REMOTE_ADDR", "")
        cur_login_info = {
            "time": timezone.now(),
            "ip": req_ip,
        }
        user.update(
            pre_login_info=user.cur_login_info,
            cur_login_info=cur_login_info
        )


class RefreshTokenView(TokenRefreshView):
    """刷新token"""

    serializer_class = CustomTokenRefreshSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)

        try:
            serializer.is_valid(raise_exception=True)
        except TokenError as e:
            raise InvalidToken(e.args[0])
        data = serializer.validated_data
        if data.get("status", "") == "success":
            return Response(data, status=200)
        return Response(data, status=400)


class LogoutView(APIView):

    permission_classes = [AllowAny, ]

    def post(self, request):
        token_tuple = get_header_token(request)
        refresh = request.data.get("refresh")
        # 不获取last_refresh剩余过期时间， 直接使用refresh的过期时间
        rexp = get_refresh_token_exp(refresh)
        if not all([token_tuple, rexp]):
            return Response(
                data={"status": "fail", "message": "请先登录"},
                status=400
            )
        username = request.user.username
        try:
            log_logout(request, username)
        except Exception:
            pass
        token, exp = token_tuple[0], token_tuple[1]
        redis_db.set(f"websoc_black_token_{token}", 1, exp)
        redis_db.set(f"websoc_black_refresh_{refresh}", 1, rexp)
        delete_token(refresh, "refresh")
        data = {"status": "success", "message": "退出成功"}
        return Response(data=data, status=200)


class ChangePasswordBase:
    def change_pw(self, user, new_password1, new_password2):

        if new_password1 != new_password2:
            return Response(data={"status": "fail", "message": "两次密码不一致"}, status=400)
        try:
            user.set_password(password=new_password1)
        except ValidationError as e:
            return Response(data={"status": "fail", "message": str(e)}, status=400)
        return Response(data={"status": "success", "message": "密码修改成功"})


class ChangePasswordView(APIView, ChangePasswordBase):
    """
    登录用户自己修改密码
    """

    def post(self, request):
        data = request.data
        old_password = data.get("old_password", "").strip()
        new_password1 = data.get("password1", "").strip()
        new_password2 = data.get("password2", "").strip()
        user = request.user
        if not user.check_password(old_password):
            return Response(data={"status": "fail", "message": "旧密码错误"}, status=400)
        log_data = {
            "module": "account_manager",
            "action": "up",
            "type": "account",
            "operator": user.username,
            "desc": {"detail": "修改密码"},
        }
        audit_log(request, **log_data)
        return self.change_pw(user, new_password1, new_password2)


class ManageChangePasswordView(APIView, ChangePasswordBase):
    def post(self, request):
        data = request.data
        new_password1 = data.get("password1", "").strip()
        new_password2 = data.get("password2", "").strip()
        username = data.get("username", "").strip()
        try:
            user = User.objects.get(username=username)
            if not admin_permission_check(user, request.user):
                raise Error403()
        except DoesNotExist:
            return Response(data={"status": "fail", "message": "用户不存在"}, status=400)
        log_data = {
            "module": "account_manager",
            "action": "up",
            "type": "account",
            "desc": {"detail": f"管理员修改用户 {username} 的密码"},
        }
        audit_log(request, **log_data)
        return self.change_pw(user, new_password1, new_password2)


class ChangeUsernameView(APIView):
    def post(self, request):
        username = request.data.get("username", "").strip()
        user = request.user
        old_username = user.username
        if username == old_username:
            return Response(
                data={"status": "success", "message": "名字一样， 没有修改"}, status=200
            )
        try:
            username = User.check_username(username)
        except ValidationError as e:
            return Response(data={"status": "fail", "message": str(e)}, status=400)
        user.username = username
        user.updated_at = timezone.now()
        user.save()
        log_data = {
            "module": "account_manager",
            "action": "up",
            "type": "account",
            "desc": {"detail": f"修改用户名 {old_username} >> {username}"},
        }
        audit_log(request, **log_data)
        return Response(data={"status": "success", "message": "修改成功"})


class ManageChangeUserPermissionView(APIView):
    def post(self, request):
        username = request.data.get("username", "").strip()
        user_groups = request.data.get("groups", [])
        if not username:
            return Response(
                data={"status": "fail", "message": "请输入需要更改权限的用户名"}, status=400
            )
        try:
            user = User.objects.get(username=username)
        except DoesNotExist:
            return Response(
                data={"status": "fail", "message": f"{username}用户不存在"}, status=400
            )
        groups = []
        for group in user_groups:
            try:
                _group = UserGroups.objects.get(group=group)
            except DoesNotExist:
                return Response(
                    data={"status": "fail", "message": f"{group} 用户角色不存在"}, status=400
                )
            else:
                groups.append(_group)
        user.group = groups
        user.updated_at = timezone.now()
        log_data = {
            "module": "account_manager",
            "action": "up",
            "type": "permission",
            "desc": {"detail": f"修改用户{username} 权限为 >> {user_groups}"},
        }
        audit_log(request, **log_data)
        return Response(data={"status": "success", "message": f"修改成功"}, status=200)


class UserInfoView(APIView):
    serializer_class = SerializerUserInfo

    def get(self, request):
        user = request.user
        user_group_id = user.group[0].user_group_id if user.group else ""
        serializer = UserSerializer(instance=user)
        data = serializer.data
        data.update({"user_group_id": user_group_id})
        validate_method = "mfa" if user.mfa else ""
        data.update({"validate_method": validate_method})
        return Response(data={"status": "success", "data": data})

    def put(self, request):
        user = request.user
        serializer = self.serializer_class(instance=user, data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.update(user, validated_data=serializer.validated_data)

        if user.username == 'admin':
            serializer.update_default_contact_email(serializer.validated_data)

        log_data = {
            "module": LogModuleName.user_management.value,
            "action": AuditLogAction.up.value,
            "type": LogTypeName.account.value,
            "desc": {
                "detail": f"编辑当前用户 {user.username} 信息"
            },
        }
        audit_log(request, **log_data)

        return Response({'status': 'success'})


class ManageUserInfoView(APIViewList, CustomGenericViewSet):

    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_fields = ['username', 'id']

    def list(self, *args, **kwargs):
        super(ManageUserInfoView, self)._initialize(self.request)
        return super(ManageUserInfoView, self).list()

    def get_queryset(self):
        queryset = self.queryset
        filtering_kwargs = self.get_kwargs_for_filtering()
        if filtering_kwargs:
            queryset = User.objects.filter(**filtering_kwargs)
        return queryset

    def get_kwargs_for_filtering(self):
        filtering_kwargs = {**self.user_query}
        for field in self.filter_fields:
            field_value = self.request.query_params.get(field)
            if field == "username" and field_value:
                filtering_kwargs["username__contains"] = field_value
            elif field_value:
                filtering_kwargs.update({field: field_value})
        return filtering_kwargs


class FreezeUserView(APIView):
    def post(self, request):
        user = request.user
        user.is_freeze = True
        user.is_active = False
        user.save()
        log_data = {
            "module": "account_manager",
            "action": "up",
            "type": "account",
            "desc": {"detail": "申请冻结用户"},
        }
        audit_log(request, **log_data)
        return Response(data={"status": "success", "message": "账号已经被冻结"}, status=200)


class ManageFreezeUserView(APIView):
    def post(self, request):
        username = request.data.get("username").strip()
        try:
            user = User.objects.get(username=username, username__ne='admin')
            if not admin_permission_check(user, request.user):
                raise Error403()
        except DoesNotExist:
            return Response(
                data={"status": "fail", "message": f"{username}用户不存在"}, status=400
            )
        user.is_freeze = True
        user.is_active = False
        user.save()
        log_data = {
            "module": "account_manager",
            "action": "up",
            "type": "account",
            "desc": {"detail": f"管理员冻结用户 {user.username}"},
        }
        audit_log(request, **log_data)
        return Response(
            data={"status": "success", "message": f"{username}用户已经被冻结"}, status=200
        )


class ManageActiveUserView(APIView):
    def post(self, request):
        username = request.data.get("username").strip()
        try:
            user = User.objects.get(username=username)
            if not admin_permission_check(user, request.user):
                raise Error403()
        except DoesNotExist:
            return Response(
                data={"status": "fail", "message": f"{username}用户不存在"}, status=400
            )
        if user.is_active and not user.is_freeze:
            return Response(
                data={"status": "fail", "message": f"{username}用户正常， 不用激活"}, status=400
            )
        user.is_freeze = False
        user.is_active = True
        user.save()
        log_data = {
            "module": "account_manager",
            "action": "up",
            "type": "account",
            "desc": {"detail": f"管理员激活用户 {user.username}"},
        }
        audit_log(request, **log_data)
        return Response(
            data={"status": "success", "message": f"{username}用户启用成功"}, status=200
        )


class QRGeneratorView(APIView):
    def get(self, request):
        username = request.user.username
        session_key = '%s_%s' % (username, 'qr_secret_key')
        # 如果生成一个key后，可使用当前key,保存在session中
        key = request.session.get(session_key)
        key, mfa_key = create_totp_qr_secret(key)
        img = create_qr_url(username, mfa_key)
        request.session[session_key] = key
        return Response(data={'status': 'success', 'data': {'img': img}}, status=200)


class MfaBindView(APIView):
    def post(self, request):
        mfa_token = request.data.get('mfa_token', '')
        if not mfa_token or len(mfa_token) < 6:
            return Response(
                data={'status': 'fail', 'message': '请输入一组正确的安全码'}, status=400
            )
        user = request.user
        if user.mfa:
            return Response(data={'status': 'fail', 'message': '用户已绑定'}, status=400)
        session_key = '%s_%s' % (user.username, 'qr_secret_key')
        qr_key = request.session.get(session_key)
        if not qr_key:
            return Response(data={'status': 'fail', 'message': '请重新获取二维码'}, status=400)
        try:
            key = unhexlify_key(qr_key)
        except Exception:
            return Response(data={'status': 'fail', 'message': '请重新获取二维码'}, status=400)
        if not verify_token(key, mfa_token):
            return Response(
                data={'status': 'fail', 'message': '验证失败，请重新输入'}, status=400
            )
        user.mfa = qr_key
        user.save()
        log_data = {
            "module": "account_manager",
            "action": "up",
            "type": "account",
            "desc": {"detail": "开启MFA认证"},
        }
        audit_log(request, **log_data)
        request.session.pop(session_key, '')
        return Response(data={'status': 'success', 'message': '启用成功'})


class MfaUnBindView(APIView):
    """ "
    MFA 解绑
    """

    def post(self, request):
        mfa_token = request.data.get('mfa_token', '')
        if not mfa_token or len(mfa_token) < 6:
            return Response(
                data={'status': 'fail', 'message': '请输入一组正确的安全码'},
                status=400
            )
        user = request.user
        key = user.mfa
        try:
            key = unhexlify_key(key)
        except Exception:
            return Response(
                data={'status': 'fail', 'message': '解绑失败，请重试'},
                status=400
            )
        if not verify_token(key, mfa_token):
            return Response(
                data={'status': 'fail', 'message': '解绑失败，请重试'},
                status=400
            )
        user.mfa = ''
        user.save()
        log_data = {
            "module": "account_manager",
            "action": "up",
            "type": "account",
            "desc": {"detail": "关闭MFA认证"}
        }
        audit_log(request, **log_data)
        return Response(data={'status': 'success', 'message': '解绑成功'})


class MfaValidateView(APIView, MfaValidateMixin):

    permission_classes = [
        AllowAny,
    ]

    def post(self, request):
        mfa_token = request.data.get('mfa_token', '')
        username = request.data.get('username', '')
        mfa_time = request.data.get('time', '')
        kind = request.data.get('kind', '')
        if not mfa_token or len(mfa_token) < 6:
            return Response(
                data={'status': 'fail', 'message': '请输入一组正确的安全码'}, status=400
            )
        if not all([username, mfa_time, kind]):
            return Response(
                data={'status': 'fail', 'message': '缺少必要参数， 请重试'}, status=400
            )
        if kind == "login":
            try:
                user = User.objects.get(username=username, is_active=True)
            except DoesNotExist:
                return Response(
                    data={'status': 'fail', 'message': f'{username} 用户不存在或者被禁用了'},
                    status=400,
                )
        else:
            user = request.user
            if isinstance(user, AnonymousUser):
                return Response(data={'status': 'fail', 'message': '请先登录'}, status=400)
        key = user.mfa
        if key:
            try:
                key = unhexlify_key(key)
            except Exception:
                return Response(
                    data={'status': 'fail', 'message': '安全码验证失败， 请重试'}, status=400
                )
            if not verify_token(key, mfa_token):
                return Response(
                    data={'status': 'fail', 'message': '安全码验证失败， 请重试'}, status=400
                )
        before_data = redis_db.get(f"{username}_{mfa_time}_{kind}")
        if not before_data:
            return Response(data={'status': 'fail', 'message': '操作超时， 请重试'}, status=400)
        redis_db.delete(f"{username}_{mfa_time}_{kind}")
        return self.mfa_after(kind, before_data)


class UserDetailView(APIView):
    serializer_class = SerializerUserDetail
    admin_exclude_keys = ('limit_targets', 'expired_time')

    def get(self, request, **kwargs):
        user_id = kwargs.get('id', '')
        serializer = self.serializer_class(User.objects.filter(user_id=user_id).first())
        return Response({'status': 'success', 'data': serializer.data})

    def put(self, request, **kwargs):
        user_id = kwargs.get('id', '')
        instance = User.objects.filter(user_id=user_id).first()
        if not instance:
            raise ValidationError('User not found.')
        if not admin_permission_check(instance, request.user):
            raise Error403()

        if instance.username == 'admin':
            for k in self.admin_exclude_keys:
                request.data.pop(k, None)
            request.data['expired_time'] = arrow.utcnow().shift(years=1000).isoformat()
            request.data['limit_targets'] = ['*']

        serializer = self.serializer_class(instance, data=self.request.data)
        serializer.is_valid(raise_exception=True)
        detail = get_user_account_log(instance, serializer.validated_data)
        serializer.update(instance, validated_data=serializer.validated_data)

        if detail:
            log_data = {
                "module": LogModuleName.user_management.value,
                "action": AuditLogAction.up.value,
                "type": LogTypeName.account.value,
                "desc": {
                    "detail": f"编辑用户 {instance.username} 的信息, {detail}。"
                },
            }
            audit_log(request, **log_data)

        return Response({'status': 'success'})


class BatchDeleteUsersView(APIView):
    def delete(self, request):
        user_id_list = request.data.get('user_ids', [])
        user_name_list = []
        obj_user_list = User.objects.filter(user_id__in=user_id_list, username__ne='admin')
        user_id_list = []
        for item in obj_user_list:
            if not admin_permission_check(item, request.user):
                continue
            user_id_list.append(item.user_id)
            user_name_list.append(item.username)
        try:
            destroy_target_groups([
                item.target_group_id for item in TargetGroups.objects.only("target_group_id").filter(user_id__in=user_id_list)])
        finally:
            for item in (User, WebReceivers):
                item.objects.filter(user_id__in=user_id_list).delete()
            for item in (CustomProfileTemplate, WhiteListKeywords, CustomKeywords):
                item.objects.filter(custom_id__in=user_id_list).delete()

        log_data = {
            "module": LogModuleName.user_management.value,
            "action": AuditLogAction.del_.value,
            "type": LogTypeName.account.value,
            "desc": {
                "detail": f"删除用户 {', '.join(user_name_list)}"
            },
        }
        audit_log(request, **log_data)

        return Response({'status': 'success'})


class InputTokenView(ModelViewSet):
    """二次开发API输入token管理， 用户使用此token可以访问本系统中有权限的接口"""

    serializer_class = InPutApiTokenSerializer
    queryset = Tokens.objects.all()

    def get_queryset(self):
        queryset = self.queryset.filter(user_id=self.request.user.user_id)
        return queryset

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.delete()
        log_data = {
            "module": "account_manager",
            "action": "del",
            "type": LogTypeName.api_token.value,
            "desc": {"detail": f"删除授权TOKEN: {instance.token}"},
        }
        audit_log(request, **log_data)
        return Response(
            data={"status": "success", "message": f"删除授权TOKEN: '{instance.token}' 成功"},
            status=200,
        )


class OutputUrlView(ModelViewSet):
    """消息推送url管理， 本系统使用此鉴权参数可以访问用户系统特定url"""

    serializer_class = OutputUrlSerializer
    queryset = OutUrls.objects.all()

    def get_queryset(self):
        queryset = self.queryset.filter(user_id=self.request.user.user_id)
        return queryset

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.delete()
        log_data = {
            "module": "account_manager",
            "action": "del",
            "type": LogTypeName.api_url.value,
            "desc": {"detail": f"删除推送URL: {instance.url}"},
        }
        audit_log(request, **log_data)
        return Response(
            data={"status": "success", "message": f"删除推送URL: '{instance.url}' 成功"},
            status=200,
        )


class OutputTestView(APIView):
    """消息推送测试"""

    def get(self, request):
        url_id = self.request.query_params.get("url_id")
        url_obj = OutUrls.objects.filter(url_id=url_id).first()
        if not url_obj:
            return Response(data={"status": "fail", "errcode": -1, "message": "token不存在"}, status=404)
        flag, message = send_message({"msg": "这是一条测试消息"}, url_obj=url_obj)
        if flag:
            return Response(data={"status": "success", "errcode": 0, "message": message}, status=200)
        return Response(
            data={"status": "fail", "errcode": -1, "message": f"推送失败, 接口响应结果是: {message}"},
            status=400
        )
